// Copyright 2009, Google Inc. All Rights Reserved.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * This code sample retrieves the data for specified dimensions/metrics.
 * The data is the following:
 *  1. data with implicit table id for specific date range;
 *	2. data with explicit table id for specific date range w/o metrics;
 *	3. visitor list limited with max-records;
 *	4. transaction list sorted by Id (descending order);
 *	5. totals aggregated by month for specific date range sorted by one metric, limited with max-records;
 */

using System;
using System.Xml;
using System.Xml.XPath;
using SampleCode.com.google.DataAPI.ReportService;

namespace ReportServiceGetDataREST
{
	public class GetData
	{
		// Set up date format.
		private const string DATE_FORMAT = "yyyy-MM-dd";
		// Provide login information.
		private const string login = "YOUR_LOGIN";
		private const string password = "YOUR_PASSWORD";
		private const int profileId = 16;
		private const string startDate = "2000-01-01";
		private const string endDate = "2009-01-01";
		private const string table = "258";
		private const string dimensions = "u:visitor_id";
		private const string metrics = "u:pages,u:visits";
		private const int maxResults = 5;

		private const string serviceURL = "http://SERVER_NAME:URCHIN_PORT/services/v1/reportservice/data";

		static void Main()
		{
			// Retrieve data with implicit table id for specific date range.
			GetDataListWithImplicitTable();
			// Retrieve data with explicit table id for specific date range w/o metrics.
			GetDataListWithExplicitTable();
			// Retrieve visitor list limited with max-records.
			GetDataListLimited();
			// Retrieve transaction list sorted by Id (descending order).
			GetDataListSorted();
			// Retrieve totals aggregated by month for specific date range sorted by one metric, limited with max-records.
			GetDataListAggregated();
		}

		/**
		 * This method retrieves data with implicit table id for specific date range.
		 */
		private static void GetDataListWithImplicitTable()
		{
			try
			{
				// Compose REST URL.
				string url = serviceURL + "?login=" + login + "&password=" + password + "&ids=" + profileId;
				url += "&start-date=" + startDate + "&end-date=" + endDate;
				url += "&dimensions=" + dimensions + "&metrics=" + metrics;
				// Retrieve data list.
				XPathDocument xPathDocument = new XPathDocument(url);
				// Process response XML.
				XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
				XmlNameTable xmlNameTable = new NameTable();
				XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlNameTable);
				xmlNamespaceManager.AddNamespace("tns", "https://urchin.com/api/urchin/v1/");
				// Get all data.
				XPathNodeIterator recordXPathNodeIterator = xPathNavigator.Select("/tns:getDataResponse/record", xmlNamespaceManager);
				// Display data info.
				DisplayDataListWithImplicitTable(recordXPathNodeIterator);
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
			}
		}

		private static void DisplayDataListWithImplicitTable(XPathNodeIterator recordXPathNodeIterator)
		{
			Console.WriteLine("Data retrieved with implicit table id for specific date range:");
			DisplayDataRecordList(recordXPathNodeIterator);
		}

		/**
		 * This method retrieves data with explicit table id for specific date range w/o metrics.
		 */
		private static void GetDataListWithExplicitTable()
		{
			try
			{
				// Compose REST URL.
				string url = serviceURL + "?login=" + login + "&password=" + password + "&ids=" + profileId;
				url += "&start-date=" + startDate + "&end-date=" + endDate;
				url += "&dimensions=" + dimensions + "&table=" + table;
				// Retrieve data list.
				XPathDocument xPathDocument = new XPathDocument(url);
				// Process response XML.
				XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
				XmlNameTable xmlNameTable = new NameTable();
				XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlNameTable);
				xmlNamespaceManager.AddNamespace("tns", "https://urchin.com/api/urchin/v1/");
				// Get all data.
				XPathNodeIterator recordXPathNodeIterator = xPathNavigator.Select("/tns:getDataResponse/record", xmlNamespaceManager);
				// Display data info.
				DisplayDataListWithExplicitTable(recordXPathNodeIterator);
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
			}
		}

		private static void DisplayDataListWithExplicitTable(XPathNodeIterator recordXPathNodeIterator)
		{
			Console.WriteLine("Data retrieved with explicit table id for specific date range w/o metrics:");
			DisplayDataRecordList(recordXPathNodeIterator);
		}

		/**
		 * This method retrieves visitor list limited with max-records.
		 */
		private static void GetDataListLimited()
		{
			try
			{
				// Compose REST URL.
				string url = serviceURL + "?login=" + login + "&password=" + password + "&ids=" + profileId;
				url += "&start-date=" + startDate + "&end-date=" + endDate;
				url += "&dimensions=" + dimensions + "&max-results=" + maxResults;
				// Retrieve data list.
				XPathDocument xPathDocument = new XPathDocument(url);
				// Process response XML.
				XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
				XmlNameTable xmlNameTable = new NameTable();
				XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlNameTable);
				xmlNamespaceManager.AddNamespace("tns", "https://urchin.com/api/urchin/v1/");
				// Get all data.
				XPathNodeIterator recordXPathNodeIterator = xPathNavigator.Select("/tns:getDataResponse/record", xmlNamespaceManager);
				// Display data info.
				DisplayDataListLimited(recordXPathNodeIterator);
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
			}
		}

		private static void DisplayDataListLimited(XPathNodeIterator recordXPathNodeIterator)
		{
			Console.WriteLine("Visitor list limited with max-records (" + maxResults + "):");
			DisplayDataRecordList(recordXPathNodeIterator);
		}

		/**
		 * This method retrieve transaction list sorted by Id (descending order).
		 */
		private static void GetDataListSorted()
		{
			try
			{
				// Compose REST URL.
				string url = serviceURL + "?login=" + login + "&password=" + password + "&ids=" + profileId;
				url += "&start-date=" + startDate + "&end-date=" + endDate;
				url += "&dimensions=u:transaction_id" + "&table=258";
				url += "&metrics=u:transactions,u:revenue";
				url += "&sort=-u:transactions";
				// Retrieve data list.
				XPathDocument xPathDocument = new XPathDocument(url);
				// Process response XML.
				XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
				XmlNameTable xmlNameTable = new NameTable();
				XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlNameTable);
				xmlNamespaceManager.AddNamespace("tns", "https://urchin.com/api/urchin/v1/");
				// Get all data.
				XPathNodeIterator recordXPathNodeIterator = xPathNavigator.Select("/tns:getDataResponse/record", xmlNamespaceManager);
				// Display data info.
				DisplayDataListSorted(recordXPathNodeIterator);
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
			}
		}

		private static void DisplayDataListSorted(XPathNodeIterator recordXPathNodeIterator)
		{
			Console.WriteLine("Transaction list sorted by Id desc:");
			DisplayDataRecordList(recordXPathNodeIterator);
		}

		/**
		 * This method retrieves totals aggregated by month for specific date range sorted by one metric, 
		 * limited with max-records.
		 */
		private static void GetDataListAggregated()
		{
			try
			{
				// Compose REST URL.
				string url = serviceURL + "?login=" + login + "&password=" + password + "&ids=" + profileId;
				url += "&start-date=" + startDate + "&end-date=" + endDate;
				url += "&dimensions=u:month" + "&table=total";
				url += "&metrics=u:hits,u:bytes";
				url += "&sort=u:hits" + "&max-results=" + maxResults;
				// Retrieve data list.
				XPathDocument xPathDocument = new XPathDocument(url);
				// Process response XML.
				XPathNavigator xPathNavigator = xPathDocument.CreateNavigator();
				XmlNameTable xmlNameTable = new NameTable();
				XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlNameTable);
				xmlNamespaceManager.AddNamespace("tns", "https://urchin.com/api/urchin/v1/");
				// Get all data.
				XPathNodeIterator recordXPathNodeIterator = xPathNavigator.Select("/tns:getDataResponse/record", xmlNamespaceManager);
				// Display data info.
				DisplayDataListAggregated(recordXPathNodeIterator);
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
			}
		}

		private static void DisplayDataListAggregated(XPathNodeIterator recordXPathNodeIterator)
		{
			Console.WriteLine("Totals aggregated by month for specific date range sorted by one metric, limited with max-records (" + maxResults + "):");
			DisplayDataRecordList(recordXPathNodeIterator);
		}

		private static void DisplayDataRecordList(XPathNodeIterator recordXPathNodeIterator)
		{
			while (recordXPathNodeIterator.MoveNext())
			{
				Console.WriteLine("Record id is \"" + recordXPathNodeIterator.Current.SelectSingleNode("recordId/text()") + "\", ");
				// Display the table dimensions.
				Console.WriteLine("dimensions are:");
				XPathNodeIterator dimensionsXPathNodeIterator = recordXPathNodeIterator.Current.Select("dimensions/dimension");
				while (dimensionsXPathNodeIterator.MoveNext())
					Console.WriteLine(" \tname: \"" + dimensionsXPathNodeIterator.Current.SelectSingleNode("@name") + "\", value: " + dimensionsXPathNodeIterator.Current.SelectSingleNode("text()"));
				// Display the table metrics.
				Console.WriteLine("metrics are:");
				XPathNodeIterator metricsXPathNodeIterator = recordXPathNodeIterator.Current.Select("metrics/*");
				while (metricsXPathNodeIterator.MoveNext())
					Console.WriteLine(" \tname: \"" + metricsXPathNodeIterator.Current.LocalName + "\", value: " + metricsXPathNodeIterator.Current.SelectSingleNode("text()"));
			}
		}
	}
}
